package org.redhat.auth.security.util;

import java.lang.reflect.Method;

import org.redhat.auth.security.user.UserDetailInfo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator;

/**
 * 权限封装类
 * 
 * @author lingen.liu
 * 
 */
public class AuthAuthorizeUtil {

	/* spring 进行权限判断的核心类 */
	private static DefaultWebInvocationPrivilegeEvaluator webInovke;

	static {
		boolean error = true;
		if (error || (error = false)) {
			try {
				Class<?> clazz = Class
						.forName("com.dayatang.domain.InstanceFactory");
				Method method = clazz.getMethod("getInstance", Class.class);
				webInovke = (DefaultWebInvocationPrivilegeEvaluator) method
						.invoke(null,
								DefaultWebInvocationPrivilegeEvaluator.class);
			} catch (Exception e) {
				error = true;
			}
		}
		if (error || (error = false)) {
			try {
				ApplicationContext ctx = new ClassPathXmlApplicationContext(
						"spring/security-context.xml");
				webInovke = ctx
						.getBean(DefaultWebInvocationPrivilegeEvaluator.class);
			} catch (Exception e) {
				error = true;
			}
		}
		if (error || (error = false)) {
			try {
				ApplicationContext ctx = new ClassPathXmlApplicationContext(
						"META-INF/spring/security-context.xml");
				webInovke = ctx
						.getBean(DefaultWebInvocationPrivilegeEvaluator.class);
			} catch (Exception e) {
				error = true;
			}
		}
	}

	/**
	 * 传入一个URL地址，判断当前登录用户是否有访问此URL的权限
	 * 
	 * 验证规则：验证必须同时验证xml中的配置及数据库中的配置
	 * 
	 * @param url
	 * @return
	 */
	public static boolean hasAuthorize(String url) {

		if (webInovke == null) {
			return false;
		}

		Authentication authentication = SecurityContextHolder.getContext()
				.getAuthentication();
		/* 检测是否能通过xml配置的权限 */
		boolean xmlAuthorize = webInovke.isAllowed(url, authentication);
		if (!xmlAuthorize) {
			return false;
		}
		UserDetailInfo loginUser = AuthUserUtil.getLoginUser();
		if (loginUser != null) {
			return loginUser.hasAuthorize(url);
		}
		return false;
	}

	/**
	 * 传入URL访问数组，当前登录用户若是拥有全部访问权限，返回true,否则返回false
	 * 
	 * @param urls
	 * @return
	 */
	public static boolean hasAllAuthorize(String[] urls) {
		for (String url : urls) {
			if (!hasAuthorize(url)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 传入URL访问数组，当前登录用户只要拥有其中一个URL的访问权限，返回true,否则返回false
	 * 
	 * @param urls
	 * @return
	 */
	public static boolean hasAnyAuthorize(String[] urls) {
		for (String url : urls) {
			if (hasAuthorize(url)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 传入一个角色，判断当前登录用户是否拥有此角色
	 * 
	 * @param role
	 * @return
	 */
	public static boolean hasRole(String role) {
		UserDetailInfo loginUser = AuthUserUtil.getLoginUser();
		if (loginUser != null) {
			return loginUser.hasRole(role);
		}
		return false;
	}

	/**
	 * 传入一角色数组，判断当前用户是否全部拥有这些角色，若拥有，返回true,否则,返回false
	 * 
	 * @param roles
	 * @return
	 */
	public static boolean hasAllRoles(String[] roles) {
		for (String role : roles) {
			if (!hasRole(role)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 传入一角色数组，判断当前用户是否拥有任意其中一个角色，若拥有，返回true,否则返回false
	 * 
	 * @param roles
	 * @return
	 */
	public static boolean hasAnyRoles(String[] roles) {
		for (String role : roles) {
			if (hasRole(role)) {
				return true;
			}
		}
		return false;
	}

}
